// 菜单明细维护
import React from 'react';
import store from '../../store'
import { message, Table, Tooltip } from 'antd';
import { Util } from 'tools';
import { Resizable } from 'react-resizable';
import CommonPagination from 'components/pagination/index';
import ColumnAuthoritysModel from 'pages/columnAuthority/ColumnAuthoritysModel';
import '../../assets/css/system.css';
import './style/index.less';

const resizeableTitle = props => {
  const { onResize, width, ...restProps } = props;
  if (!width) {
    return <th {...restProps} />;
  }
  return (
    <Resizable
      width={width}
      height={0}
      onResize={onResize}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      <th {...restProps} />
    </Resizable>
  );
};
/**
  需要传入一个名为 param 的对象，对象包含的参数如下：
  1、columns --- table的表头
  2、data --- table表格数据
  3、isOnRow --- 是否可以操作行 true||false 可以操作即需要传入，且需要提供相对应得方法(onClickRowPublic); 不可以操作即不需要传
  4、total --- 列表数据总条数，默认为0，需要分页则传，不需要则不传
  5、page --- 当前得页数，默认为第一页
  6、rowClassName --- 操作行之后是否需要给当前选中的那条数据加上背景颜色，需要的话即需提供 setRowClassNamePublic 方法
  7、height --- 表格的高度，默认为store.getState().tableHeight.y + 45 + 'px'
  8、x, y --- 表格的scroll值，x默认为900， y默认为store.getStqqIDtate().tableHeight.y
  9、pageSize --- 默认为10条则不传，默认为20条则传非空
  10、cls ---  初始化设置table的高度以及表体的高度 传入

注意: 
  1、当table数据请求成功之后需要调用此组件中的handleLoading关闭loading，或者在组件加载完成之后关闭也可以。
  2、必须向该组件传入一个compilePage方法改变分页条数与页数
*/

export default class PubilcTablePagination extends React.Component {

  constructor() {
    super();
    this.state = {
      userData: React.$getSessionData(),
      loading: true,
      columns: [],
      copyColumns: [],
      headHeight: 0,
      tableData: []
    };
    this.timer = null;
  }

  componentDidMount() {
    // 初始化设置table的高度以及表体的高度
    this.props.onRef && this.props.onRef(this)
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    //该方法内禁止访问this
    let propsColumns = nextProps.param?.columns || [];
    if (JSON.stringify(propsColumns) !== JSON.stringify(prevState.copyColumns)) {
      // let columns = Util.customDeepCopy(propsColumns); // 深拷贝数据
      return {
        columns: propsColumns,
        copyColumns: Util.customDeepCopy(propsColumns)
      }
    }
    let tableData = nextProps.param?.data || [];
    if (JSON.stringify(tableData) !== JSON.stringify(prevState.tableData)) {
      return {
        tableData
      }
    }
    //不需要更新状态，返回null
    return null
  }

  componentDidUpdate(nextProps, prevState) {
    let propsColumns = nextProps.param?.columns || [];
    let componentName = nextProps.param?.componentName || '';
    if (componentName && (JSON.stringify(propsColumns) !== JSON.stringify(this.state.copyColumns))) {
      // console.log("propsColumns", propsColumns)
      // console.log("copyColumns", this.state.copyColumns)
      // console.log("触发了componentDidUpdate")
      let { columns } = this.state;
      for (let i = 0; i < columns.length; i++) {
        let item = columns[i];
        let index = i;
        columns[i].fixed = item.fixed === 'L' ? 'left' : (item.fixed === 'R' ? 'right' : (item?.fixed || undefined));
        columns[i].ellipsis = item && 'ellipsis' in item ? item.ellipsis : false;
        columns[i].onHeaderCell = column => ({
          width: parseInt(column.width),
          onResize: this.handleResize(index),
        });
        if (item?.isRender !== 'N') { // 行内编辑避免重新渲染
          columns[i].render = item && 'render' in item && item.tooltip !== 'Y' ? item.render : (text, record) => {
            if (item?.tooltip !== 'N') { // 默认展示Tooltip，特殊处理为N则不展示Tooltip
              return (
                <Tooltip title={text}>
                  <span className="ellipsis" style={{ width: '100%', display: 'block' }}>{text}</span>
                </Tooltip>
              )
            } else {
              return text;
            }
          }
        }
      }
      this.setState({ columns }, () => {
        this.getTableHeadHeight();
      });
    }
    let tableData = nextProps.param?.data || [];
    if ((JSON.stringify(tableData) !== JSON.stringify(this.state.tableData))) {
      this.getTableHeadHeight();
    }
  }

  componentWillUnmount() {
    // 组件销毁前将静止让setState修改state的状态
    this.setState = (state, callback) => { return; }
  }

  handleResize = index => (e, { size }) => {
    let componentName = this.props.param && 'componentName' in this.props.param && this.props.param.componentName ? this.props.param.componentName : '';
    if (componentName) {
      this.state.columns[index].width = parseInt(size?.width || this.state.columns[index].width);
      this.setState({}, () => {
        this.handleDebounce(componentName);
      });
    }
  }

  // 只保留最后一次操作数据
  handleDebounce(componentName) {
    clearTimeout(this.timer);
    this.timer = setTimeout(() => {
      this.handleSaveWidthByUser(componentName)
    }, 500);
  }

  /**
  * @ByShizi: 按用户保存拖拽后的宽度
  * Create 2023-01-03
  * */
  handleSaveWidthByUser = async (componentName) => {
    try {
      const { userData, columns } = this.state;
      let alignObj = {
        center: 'C',
        left: 'L',
        right: 'R'
      };
      let filterColumns = columns && columns.filter(item => {
        return !!(item?.ID || item?.id || '')
      });
      let data = {
        params: [{
          type: 'U',
          compontName: componentName,
          language: userData?.language || 'CN',
          updateUser: userData?.userID || '',
          tableData: filterColumns && filterColumns.map((item) => {
            return {
              type: 'C',
              code: item.code,
              ID: item?.id || item?.ID || '',
              align: item && item.align && (item.align === 'left' || item.align === 'center' || item.align === 'right') ? alignObj[item.align] : 'C',
              columnName: item.descripts,
              displayFlag: item.display,
              pringFlag: item?.printFlag || 'N',
              enDescripts: item.enDescripts,
              exportFlag: item.exportFlag,
              width: item && item.width ? parseInt(item.width) : undefined,
            }
          })
        }]
      }
      let res = await React.$asyncPost(this, '01040039', data);
      message.success(res?.errorMessage || '列宽修改成功');
      this.getTableHeadHeight();
    } catch (error) {
      console.log(error)
    }
  }

  // 暴露给外部关闭loading的方法
  handleLoading = () => {
    this.setState({ loading: false })
  }

  // 页码改变的回调，参数是改变后的页码及每页条
  onChange = (page, pageSize) => {
    if (this.props && this.props.compilePage) {
      this.props.compilePage(page, pageSize)
    } else {
      this.props.handelThis.compilePage(page, pageSize);
    }
  }

  // 条数改变的回调
  onShowSizeChange = (current, size) => {
    if (this.props && this.props.compilePage) {
      this.props.compilePage(1, size)
    } else {
      this.props.handelThis.compilePage(1, size);
    }
  }

  // 显示分页总条数
  showTotal(total) {
    return `共 ${total} 条`;
  }

  // 双击表头触发表头数据维护
  handleRowSelection = () => {
    return {
      onDoubleClick: () => {
        this.columnRef && this.columnRef.onOpenModel();
      },
    };
  }

  // 获取当前table表头高度
  getTableHeadHeight = () => {
    let _key = this.props.param && '_key' in this.props.param && this.props.param._key ? this.props.param._key : '';
    let headDom = document.querySelector('.public-table-pagination-content' + _key + ' .ant-table-thead');
    let headHeight = headDom?.clientHeight || headDom?.offsetHeight || 45;
    if (document.querySelector('.public-table-pagination-content' + _key + ' .ant-table-placeholder')) {
      document.querySelector('.public-table-pagination-content' + _key + ' .ant-table-placeholder').style.top = headHeight + 1 + 'px';
      document.querySelector('.public-table-pagination-content' + _key + ' .ant-table-placeholder').style.height = 'calc(100% - ' + headHeight + 'px)';
    }
    if ((headHeight - 45) !== this.state.headHeight) {
      this.setState({ headHeight: headHeight - 45 });
    }
  }

  // 获取表头数据
  handleReloadCloumnsData = () => {
    this.props && this.props.getColumns && this.props.getColumns();
    this.getTableHeadHeight();
  }

  render() {
    const { columns, headHeight } = this.state;
    let _key = this.props.param && '_key' in this.props.param && this.props.param._key ? this.props.param._key : '';
    let isComplete = !this.props.param.isComplete ? true : false;
    let isOnHeadRow = this.props.param.isOnHeadRow ? true : false;
    let rowKey = this.props.param && 'rowKey' in this.props.param && this.props.param.rowKey ? this.props.param.rowKey : '';
    let isPagination = (this.props.param.page && this.props.param.page > 0) || (this.props.param.page && this.props.param.page === 0) ? true : false;
    let componentName = this.props.param && 'componentName' in this.props.param && this.props.param.componentName ? this.props.param.componentName : '';
    let isColumnModal = componentName && this.props.getColumns ? true : false;
    let currentTableClassName = 'public-table-pagination-content' + _key; // 用于相同界面使用获取表头高度问题

    return (
      <div style={{ height: '100%' }} className={this.props.cls + (componentName ? ' public-table-pagination' : '')}>
        <Table
          title={this.props.title ? this.props.title : null}
          style={{ height: this.props.cls && this.props.cls ? store.getState().tableHeight.y + this.props.wrapperHeight + 'px' : (this.props.param.height ? this.props.param.height : store.getState().tableHeight.y + 45 + 'px') }}
          // columns={this.props.param.columns || []}
          columns={columns}
          dataSource={this.props.param.data ? this.props.param.data : []}
          pagination={false}
          onRow={this.props.onClickRowPublic ? (record, index) => this.props.onClickRowPublic(record, index) : ''}
          onHeaderRow={(isOnHeadRow && (this.props.onClickHeadRowPublic)) ? (record) => this.props.onClickHeadRowPublic(record) : (isColumnModal ? this.handleRowSelection : () => { })}
          rowSelection={this.props.rowSelectionPublic ? this.props.rowSelectionPublic : null}
          rowClassName={this.props.setRowClassNamePublic ? (record) => this.props.setRowClassNamePublic(record) : ''}
          scroll={{
            x: this.props.param.x ? (this.props.param.x === 'none' || this.props.param.x === 'N' ? false : this.props.param.x) : 900,
            y: this.props.param.y === 'N' ? false : (this.props.param.y ? parseInt(this.props.param.y) - headHeight : store.getState().tableHeight.y - headHeight)
          }}
          bordered={this.props.param && 'bordered' in this.props.param ? this.props.param.bordered : true}
          loading={this.props.param.loading ? this.props.param.loading : false}
          className={currentTableClassName + ' ' + (this.props.param.TableClassName ? this.props.param.TableClassName : '')}
          rowKey={(row) => {
            return rowKey ? row[rowKey] : ('key' in row ? row.key : row.id)
          }}
          components={{
            header: {
              cell: resizeableTitle,
            },
          }}
        />
        {isPagination ? (
          <CommonPagination
            company={this.props.param.company ? this.props.param.company : ''}
            size={this.props.param.size ? this.props.param.size : 'small'}
            current={this.props.param.page ? this.props.param.page : 1}
            total={this.props.param.total ? this.props.param.total : 0}
            search={this.props.param.search ? this.props.param.search : 'search'}
            onShowSizeChange={this.onShowSizeChange}
            complete={isComplete}
            dataSource={this.props.param.data ? this.props.param.data : []}
            loading={this.props.param.loading}
            onChange={this.onChange}
            pageSize={this.props.param.pageSize ? this.props.param.pageSize : ''}
          />
        ) : ''}
        {isColumnModal ? (
          <ColumnAuthoritysModel
            clientWidth='800px'
            compontName={this.props.param.componentName}
            configType="C"
            onRef={ref => this.columnRef = ref}
            reloadData={this.handleReloadCloumnsData}
          />
        ) : ''}
      </div>
    );
  }
}
